﻿/**
 * @filename:	ColorPanel.js
 * @author:	baboo
 * @description:
 * you should define colorpanel styles like follow:
 * <style>
 *   #ColorPanelId{border:1px solid #000;width:245px}
 *   #ColorPanelId dd{margin:0}
 *   .CP_HEAD{BORDER-BOTTOM:1PX DOUBLE #000;BACKGROUND:#004080;COLOR:#FFF;HEIGHT:20PX;LINE-HEIGHT:20PX;PADDING-LEFT:10PX}
 *   .CP_BODY{BACKGROUND:#FFF}
 *   .CP_BASECOLORPNL{FLOAT:LEFT;MARGIN:10PX}
 *   .CP_GRAYPNL{FLOAT:LEFT;MARGIN:10PX}
 *   .CP_FOOT{CLEAR:BOTH}
 *   .CP_PREVIEW{FLOAT:LEFT;WIDTH:50PX;HEIGHT:20PX;BORDER:1PX SOLID #000;MARGIN:0 5PX 5PX 10PX}
 *   .CP_PREVIEWSET{FLOAT:LEFT;MARGIN:0 5PX 5PX 0;COLOR:#999}
 *   .CP_BUTTONS{FLOAT:LEFT;MARGIN-LEFT:30PX;HEIGHT:25PX;LINE-HEIGHT:25PX}
 *   .CP_BUTTONS A{DISPLAY:BLOCK;FLOAT:LEFT;MARGIN-LEFT:10PX;COLOR:#004080}
 * </style> 
 * create it like:
 * 	var cp = new $.ColorPanel({onok: function(c){$('input[type=text][:last]').e.value = c;}});
 *	cp.install($('#ColorPanel').e);
 */
$.ColorPanel = $({
	__init : function (sets) {
		sets = $.extend({
			cellSize : [6,3],
			id : 'ColorPanelId',
			title : '我是颜色选择器'
		}, sets || {});	
		
		/**
		 * Tool fun
		 */
		var oct2hex = function (oct){oct = Math.round(oct);var hexStr = '0123456789ABCDEF';var l = oct % 16;var h = Math.floor(oct / 16) % 16;return hexStr.charAt(h) + hexStr.charAt(l);};
		var rgb2hex = function (r, g, b) { return '#' + oct2hex(r) + oct2hex(g) + oct2hex(b) };
		var $color = function (c, l) {
    		var r, g, b;
    		r = '0x' + c.substring(1, 3);
    		g = '0x' + c.substring(3, 5);
    		b = '0x' + c.substring(5, 7);

    		if (l > 120) {
      			l = l - 120;
      			r = (r * (120 - l) + 255 * l) / 120;
      			g = (g * (120 - l) + 255 * l) / 120;
      			b = (b * (120 - l) + 255 * l) / 120;
    		} else {
	      		r = (r * l) / 120;
    	  		g = (g * l) / 120;
      			b = (b * l) / 120;
    		}
    		return rgb2hex(r, g, b);
  		};
  		var resetGrayTable = function (c) {
    		for(i = 0; i <= 30; i ++) {
      			grayTds.item(i * 2).bgColor = $color(c, 240 - i * 8);
    		} 
    		if (sets.lastGLE) {
    			setGrayLevelSelected(sets.lastGLE, 1);
    		}
  		};
  		var setBaseColorSelected = function (d, flag) {
  			if (flag) {
  				if (sets.lastBCE) setBaseColorSelected(sets.lastBCE, 0);
  				d.style.width = d.style.height = (sets.cellSize[0] - 2) + 'px';
  				d.style.border = '1px solid #000';
  				sets.lastBCE = d;
  				resetGrayTable(d.title);
  			} else {
  				d.style.width = d.style.height = sets.cellSize[0] + 'px';
  				d.style.border = '0';
  			}
  		};
  		var setGrayLevelSelected = function (tr, flag) {
  			if (flag) {
  				if (sets.lastGLE) setGrayLevelSelected(sets.lastGLE, 0);	
  				var tds = $('td', tr);
  				tds.$(1, 'bgColor', tds.item(0).bgColor);
  				sets.lastGLE = tr;
  			} else {
  				$('td', tr).$(1, 'bgColor', '#ffffff');
  			}
  		};
  		var showColor = function (bce, gle) {
  			var bce = bce || sets.lastBCE, gle = gle || sets.lastGLE;
  			if (!bce || !gle) return;
  			var color = $color(bce.title, gle.getElementsByTagName('td').item(0).title);
  			showE.css('background:' + color);
  			return color;
  		};
  		
		e = $('<dl style="display:none"><dt class="CP_HEAD"><em>' + sets.title + '</em></dt></dl>');
		e.id = sets.id;
		var baseColorPnlHtml = (function(){
			var htmlArr = [], cNum = [1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0], i, j, n1, n2, n3, r, g, b, hc;
			htmlArr.push(['<div style="width:', sets.cellSize[0] * 30, 'px;height:',
						 sets.cellSize[0] * 16, 'px" class="CP_BASECOLORPNL">'].join(''));
			for (i = 0; i < 16; i ++) {
				for (j = 0; j < 30; j ++) {
					n1 = j % 5;
        			n2 = Math.floor(j / 5) * 3;
        			n3 = n2 + 3;
        			r = cNum[n3] * n1 + cNum[n2] * (5 - n1);
        			g = cNum[n3 + 1] * n1 + cNum[n2 + 1] * (5 - n1);
        			b = cNum[n3 + 2] * n1 + cNum[n2 + 2] * (5 - n1);
        			r = ((r * 16 + r) * 3 * (15 - i) + 0x80 * i) / 15;
    				g = ((g * 16 + g) * 3 * (15 - i) + 0x80 * i) / 15;
    				b = ((b * 16 + b) * 3 * (15 - i) + 0x80 * i) / 15;
    				hc = rgb2hex(r, g, b);
        			htmlArr.push(['<div style="background:', hc, ';font-size:0px;width:',
        						sets.cellSize[0], 'px;height:', sets.cellSize[0], 'px;float:left" title="',
        						hc, '"></div>'].join(''));
				}
			}
			htmlArr.push('</div>');	
			return htmlArr.join('');
		})();
		var grayPnlHtml = (function(){
			var htmlArr = [];
			htmlArr.push('<TABLE class="CP_GRAYPNL" style="cursor:pointer;width:22px;" cellspacing="0" cellpadding="0"><TBODY>');
    		for(i = 255; i >= 0; i -= 8.5) {
      			htmlArr.push('<TR><TD bgcolor="' + rgb2hex(i, i, i) + '" TITLE=' + Math.floor(i * 16 / 17) + 
      						 ' style="height:' + sets.cellSize[1] + 'px;width:20px;"></TD><TD style="width:' +
      						 sets.cellSize[1] + 'px"></TD></TR>');
    		}
    		htmlArr.push('</TBODY></TABLE>');
    		htmlArr.push('<div style="font-size:0;clear:both;height:0px"></div>');
    		return htmlArr.join('');
		})();
		var body = $('<dd class="CP_BODY"></dd>');
		body.innerHTML = baseColorPnlHtml + grayPnlHtml;
		var foot = $(['<dd class="CP_FOOT"><div class="CP_PREVIEW"></div>',
					  '<div class="CP_PREVIEWSET"><input type="checkbox"/>预览</div>',
					  '<div class="CP_BUTTONS"><a class="CP_OKBTN" href="#">确定</a>',
					  '<a class="CP_CANCELBTN" href="#">取消</a></div><div style="font-size:0;clear:both"></div></dd>'].join(''));
		e.appendChild(body);
		e.appendChild(foot);
		e = $(e);
		var grayTds = $('table.CP_GRAYPNL td', body);
		var showE = $('div.CP_PREVIEW', foot);
		var preview = $('div input[type=checkbox]', foot).e;
		//bind event
		(function(){
			$('div a.CP_OKBTN', foot).click(function(){
				if (sets.onok) sets.onok(showColor());
				e.$('$hide');
			});
			$('div a.CP_CANCELBTN', foot).click(function(){
				e.$('$hide');
			});
			$('div.CP_BASECOLORPNL', body).mouseover(function(event){
				if(preview.checked) {
					showColor($(event, 'find', 'div'));	
				}
			}).click(function(event){
				var o = $(event, 'find', 'div');
				setBaseColorSelected(o, 1);
				showColor();
			}).mouseout(function(){
				if (preview.checked) showColor();
			});
			$('table.CP_GRAYPNL', body).mouseover(function(event){
				if(preview.checked) {
					showColor(false, $(event, 'find', 'tr'));	
				}
			}).click(function(event){
				var o = $(event, 'find', 'tr');
				setGrayLevelSelected(o, 1);
				showColor();
			}).mouseout(function(){
				if (preview.checked) showColor();
			});
		})();
		this.e = e;
		setGrayLevelSelected($('table.CP_GRAYPNL tr[15]', body).e, 1);
		setBaseColorSelected($('div.CP_BASECOLORPNL div[0]', body).e, 1);
		showColor();
	},
  	install : function (p) { p.appendChild(this.e.e) },
  	show : function () { this.e.$('$show') }
});
$.ColorPanel.version = 20080305